package org.study.redis.search.boot.controller;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.*;

/**
 * Redis缓存监控。参考 https://www.imooc.com/article/325132
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2025年04月27日
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/redis")
public class RedisController {
    private final RedisTemplate redisTemplate;

    /**
     * 查询redis信息
     *
     * @return
     */
    @GetMapping("/info")
    public Map<String, Object> memory() {
        Map<String, Object> result = Maps.newHashMap();
        // 获取redis缓存完整信息
        Properties info = (Properties) redisTemplate.execute((RedisCallback) redisConnection -> redisConnection.info());
        result.put("info", info);
        // 参数选项：server(有关Redis服务器的常规信息)、clients(客户端连接部分)、memory(内存消耗相关信息)、persistence(RDB和AOF相关信息)、
        // stats(一般统计)、replication(主/副本复制信息)、cpu(CPU消耗统计信息)、commandstats(Redis命令统计)、cluster(Redis群集部分)、
        // keyspace(与数据库相关的统计)、all(所有部分)、default
        Properties memoryInfo = (Properties) redisTemplate.execute((RedisCallback) redisConnection -> redisConnection.info("memory"));
        result.put("memoryInfo", memoryInfo);
        // 获取redis缓存中可用键Key的总数
        Object dbSize = redisTemplate.execute((RedisCallback) redisConnection -> redisConnection.dbSize());
        result.put("dbSize", dbSize);

        result.put("datetime", DateUtil.format(LocalDateTime.now(), DatePattern.NORM_DATETIME_PATTERN));

        List<Map<String, String>> pieList = new ArrayList<>();
        // 获取redis缓存命令统计信息
        Properties commandStats = (Properties) redisTemplate.execute((RedisCallback) redisConnection -> redisConnection.info("commandstats"));
        commandStats.stringPropertyNames().forEach(key -> {
            Map<String, String> data = new HashMap<>(4);
            String property = commandStats.getProperty(key);
            data.put("name", StrUtil.removePrefix(key, "cmdstat_"));
            data.put("value", StrUtil.subBetween(property, "calls=", ",usec"));
            pieList.add(data);
        });
        result.put("commandStats", pieList);
        return result;
    }
}
